package org.self.activitidemo.service.impl;

import com.alibaba.fastjson.JSONObject;
import org.self.activitidemo.model.Tasks;
import org.activiti.engine.*;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.self.activitidemo.service.LeaveWorkflowService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 请假流程Service
 *
 * @author HenryYan
 */
@Component
@Transactional
public class LeaveWorkflowServiceImpl implements LeaveWorkflowService {

    private static Logger logger = LoggerFactory.getLogger(LeaveWorkflowServiceImpl.class);

    private RuntimeService runtimeService;

    protected TaskService taskService;

    protected HistoryService historyService;

    protected RepositoryService repositoryService;

    @Autowired
    private IdentityService identityService;

    /**
     * 启动流程
     *
     * @param
     */
    public ProcessInstance startWorkflow(String userId, String processName, Map<String, Object> variables) {
        String businessKey = new Date().toString();
        ProcessInstance processInstance = null;
        try {
            // 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
            identityService.setAuthenticatedUserId(userId);
            processInstance = runtimeService.startProcessInstanceByKey(processName, businessKey, variables);
            String processInstanceId = processInstance.getId();
            logger.debug("start process of {key={}, bkey={}, pid={}, variables={}}", new Object[]{"process", businessKey, processInstanceId, variables});
        } finally {
            identityService.setAuthenticatedUserId(null);
        }
        return processInstance;
    }

    /**
     * 查询待办任务
     *
     * @param userId 用户ID
     * @return
     */
    public String findTodoTasks(String userId) {
        TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);
        List<Task> tasks = taskQuery.list();
        Tasks resultTasks = new Tasks();
        JSONObject result = new JSONObject();
        if (tasks.size() != 0)
        {
            for (int i = 0; i < tasks.size(); i++ ) {
                resultTasks.setId(tasks.get(i).getId());
                resultTasks.setName(tasks.get(i).getName());
                resultTasks.setAssignee(tasks.get(i).getAssignee());
                resultTasks.setCreateDate(tasks.get(i).getCreateTime());
                resultTasks.setExecutionId(tasks.get(i).getExecutionId());
                resultTasks.setProcessDefinitionId(tasks.get(i).getProcessDefinitionId());
                resultTasks.setProcessInstanceId(tasks.get(i).getProcessInstanceId());
                result.put("data", resultTasks);
            }
            result.put("status", "success");
        }
        else
            result.put("status", "none");
        return result.toString();
    }

    /**
     * 签收
     * @param userId
     * @param taskId
     * @return
     */
    public String claim(String userId, String taskId) {
        taskService.claim(taskId, userId);
        JSONObject result = new JSONObject();
        result.put("status", "success");
        return result.toString();
    }

    public String complete(String userId, String taskId, Map<String, Object> variablesMap){
        JSONObject result = new JSONObject();
        try {
            String processInstanceId = null;
            Task task=taskService.createTaskQuery().taskId(taskId).singleResult();
            if (task.getProcessInstanceId() != null) {
                processInstanceId = task.getProcessInstanceId();
            }
            taskService.complete(taskId, variablesMap);
            result.put("status", "success");
            return result.toString();
        } catch (Exception e) {
            logger.error("error on complete task{}, variables={}", new Object[]{taskId, variablesMap, e});
            result.put("status", "error");
            return result.toString();
        }
    }

    /**
     * 查询流程定义对象
     *
     * @param processDefinitionId 流程定义ID
     * @return
     */
    protected ProcessDefinition getProcessDefinition(String processDefinitionId) {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
        return processDefinition;
    }

    @Autowired
    public void setRuntimeService(RuntimeService runtimeService) {
        this.runtimeService = runtimeService;
    }

    @Autowired
    public void setTaskService(TaskService taskService) {
        this.taskService = taskService;
    }

    @Autowired
    public void setHistoryService(HistoryService historyService) {
        this.historyService = historyService;
    }

    @Autowired
    public void setRepositoryService(RepositoryService repositoryService) {
        this.repositoryService = repositoryService;
    }

}
